import objects
from utils import Directions, is_solid, RenderRepr


class Character(objects.Object):
    target_layer = "characters"

    def __init__(self):
        super().__init__()
        self.properties = {"walk_speed": None}
        self.inventory = []

    def can_enter(self, tile):
        if not is_solid(tile["floor"].obj):
            return False
        if len(tile["characters"]) > 0:
            return False
        if is_solid(tile["wall"].obj):
            return False
        return True

    def walk_direction(self, direction):
        """Character tries to walk in target direction specified either by
            a name as defined in Drections, a number as defined in Directions
            or as a (dx, dy) tuple.

        """
        if isinstance(direction, tuple):
            []
        if isinstance(direction, str):
            direction = Directions.__dict__[direction]
        new_tile = self.tile.around_tiles[direction]
        if self.can_enter(new_tile):
            self.move_to_tile(new_tile)
            return True
        else:
            return False

    def turn(self):
        pass

    def pick_up(self, item):
        if not item in self.tile["items"]:
            return False
        item.picked_up(self)
        return True

    def drop(self, item):
        if not item in self.inventory:
            return False
        item.dropped(who)
        return True

    def __getattr__(self, attr):
        if attr in self.properties:
            value = self.properties[attr]
            value_type = type(value)
            for item in self.inventory:  # Maybe change this to faster way (adding and removing effects in pickup/drop)
                if attr in item.effects:  # TODO: Add priority.
                    effect = item.effects[attr]
                    if effect[0] == "+":
                        value += effect[1]
                    elif effect[0] == "*":
                        value *= effect[1]
                    elif effect[0] == "fun":
                        value = effect[1](value)
            return value_type(value)
        raise AttributeError("'{0}' object has no attribute '{1}'"
                             .format(self.__class__.__name__, attr))


class Monster(Character):
    def __init__(self):
        super().__init__()
        self.properties["walk_speed"] = 50
        self.render_repr = RenderRepr("m", (200, 150, 150), None)

    def place_on_map(self, target_tile):
        super().place_on_map(target_tile)
        self.game.add_task(0, self.turn)

    def turn(self):
        self.walk_direction(self.game.rnd.randint(0, 7))
        self.game.add_task(self.walk_speed, self.turn)
